import pandas as pd

def get_fvid_vid_same_cid(data, df_vid_info):
    data.loc[data['cid'] == data['fvid_cid'], 'fvid_vid_same_cid'] = 1
    return data

def get_update_vid(data, df_vid_info):
    data.loc[(data['cid'] == data['fvid_cid']) &(data['serialno'] < data['fvid_serialno']), 'update_vid'] = 1
    return data

def get_update_vid_abs(data, df_vid_info,n):
    data.loc[(data['cid'] == data['fvid_cid']) & (abs(data['serialno'] - data['fvid_serialno'])<=n), 'update_vid_abs'] = 1
    return data

def get_vid_last_click_time_diff(data, df_click_data, rank=3):
    df = data.copy()
    time_gap_data = df_click_data[df_click_data['rank']==rank][['did','vid', 'time_gap']].rename(columns={'time_gap':'vid_last_click_time_diff'})
    df = pd.merge(df,time_gap_data, on=['did','vid'],how='left')
    return df

def feature_click_unique(data, df_click_data, group_key, key):
    df_feats = df_click_data.groupby(group_key)[key].nunique()
    data[f'nunique_click_{group_key}_{key}'] = data[group_key].map(df_feats)
    return data


def feature_cross_count(data, df, group_list):
    df_feats = df.groupby(group_list)['hb'].count().reset_index().rename(
        columns={'hb': f'cross_count_{group_list[0]}_{group_list[1]}'})
    data = data.merge(df_feats, on=group_list, how='left')
    return data

def feature_cross_sum(data, df_click_data, group_list):
    df_feats = df_click_data.groupby(group_list)['vts'].sum().reset_index().rename(
        columns={'vts': f'cross_sum_{group_list[0]}_{group_list[1]}'})
    data = data.merge(df_feats, on=group_list, how='left')
    return data

def feature_cross_mean(data, df_click_data, group_list):
    df_feats = df_click_data.groupby(group_list)['vts'].mean().reset_index().rename(
        columns={'vts': f'cross_mean_{group_list[0]}_{group_list[1]}'})
    data = data.merge(df_feats, on=group_list, how='left')
    return data


def reduce_mem_usage(df, verbose=True):
    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
    start_mem = df.memory_usage().sum() / 1024**2
    cols_ = [col for col in list(df) if col not in ['cid', 'vid']]
    for col in cols_:
        col_type = df[col].dtypes
        if col_type in numerics:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
    end_mem = df.memory_usage().sum() / 1024**2
    if verbose:
        print('Mem. usage decreased to {:5.2f} Mb({:.1f}% reduction)'.format(
            end_mem, 100 * (start_mem - end_mem) / start_mem))
    return df